-- card: 10186 from stack: in -- bmap block id: 10283 -- flags: 0000 -- background id: 8327 -- name: FindInField ----- HyperTalk script ----- on opencard set the visible of field 1 to false -- background field set the scroll of card field 1 to 0 end opencard on closecard set the visible of field 1 to true end closecard on showIt pos,theLength put item 1 of the rect of card field 1 into x put item 2 of the rect of card field 1 into y put item 3 of pos into theChar put item 2 of pos into theLine put the textHeight of card field 1 into th put 6 into ts -- courier put y+(theLine*th) into y put the scroll of card field 1 into theScroll get the rect of card field 1 put item 4 of it - item 2 of it into theHeight if (theScroll+theHeight) < y then set the scroll of card field 1 to (y-10*th) end if put x+(theChar*ts) into x put y - the scroll of card field 1 into y put x into item 1 of theLoc1 put y into item 2 of theLoc1 put x + theLength*ts into item 1 of theLoc2 put y into item 2 of theLoc2 click at theloc1 -- this causes the whole word to be selected drag from theLoc1 to theLoc2 -- but otherwise I only get an -- insertion bar! wait for 1 seconds end showIt -- part 5 (field) -- low flags: 00 -- high flags: 2007 -- rect: left=18 top=32 right=290 bottom=384 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 0 -- font id: 22 -- text size: 10 -- style flags: 0 -- line height: 13 -- part name: XCMD Text -- part 6 (button) -- low flags: 00 -- high flags: 8003 -- rect: left=304 top=299 right=321 bottom=425 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 1 -- font id: 0 -- text size: 12 -- style flags: 0 -- line height: 16 -- part name: Show LSC Source ----- HyperTalk script ----- on mouseUp get the visible of card field "source" set the visible of card field "source" to not it if it is false then set the name of me to "Hide LSC Source" else set the name of me to "Show LSC Source" end if end mouseUp -- part 9 (field) -- low flags: 00 -- high flags: 0004 -- rect: left=389 top=268 right=289 bottom=483 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 0 -- font id: 3 -- text size: 12 -- style flags: 0 -- line height: 16 -- part name: found -- part 10 (button) -- low flags: 00 -- high flags: 2000 -- rect: left=395 top=76 right=111 bottom=480 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 1 -- font id: 0 -- text size: 12 -- style flags: 0 -- line height: 16 -- part name: Not case ----- HyperTalk script ----- on mouseUp ask "Find what?" put it into myTarget if myTarget is not empty then set the scroll of card field 1 to 0 get FindInField(card field 1,myTarget,"true",0) put it into card field "found" showIt it,the number of chars in myTarget end if end mouseUp -- part 11 (button) -- low flags: 00 -- high flags: 2000 -- rect: left=395 top=123 right=158 bottom=480 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 1 -- font id: 0 -- text size: 12 -- style flags: 0 -- line height: 16 -- part name: New Button ----- HyperTalk script ----- on mouseUp ask "Find what?" put it into myTarget if myTarget is not empty then set the scroll of card field 1 to 0 get FindInField(card field 1,myTarget,"",0) put it into card field "found" showIt it,the number of chars in myTarget end if end mouseUp -- part 12 (button) -- low flags: 00 -- high flags: 2000 -- rect: left=395 top=169 right=215 bottom=480 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 1 -- font id: 0 -- text size: 12 -- style flags: 0 -- line height: 16 -- part name: New Button ----- HyperTalk script ----- on mouseUp ask "Show what?" if it is not empty then hide message set the scroll of card field 1 to 0 put it into target put false into done put 0 into start --put empty into msg repeat while done is false get FindInField(card field 1,target,"",start) if item 1 of it is 0 then put true into done else put it into card field "found" showIt it,the number of chars in target put item 1 of it + 1 into start end if end repeat end if end mouseUp -- part 14 (button) -- low flags: 00 -- high flags: 0000 -- rect: left=395 top=46 right=64 bottom=468 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 1 -- font id: 0 -- text size: 12 -- style flags: 0 -- line height: 16 -- part name: New Button -- part 7 (field) -- low flags: 81 -- high flags: 0007 -- rect: left=18 top=31 right=290 bottom=489 -- title width / last selected line: 0 -- icon id / first selected line: 0 / 0 -- text alignment: 0 -- font id: 3 -- text size: 10 -- style flags: 0 -- line height: 13 -- part name: source -- part contents for card part 5 ----- text ----- FindInField version 1.3 Roger Brown The FindInField XFCN locates a string in a given field or container as fast as HyperCard can. It searches only the specified container. You can specify a starting position and whether or not the search is case sensitive. It returns information on the location of the find: item 1 is the byte position in the string (1-based) item 2 is the line number in the string item 3 is the byte position in the line (1-based) --- all are zero if the string is not found INVOKING FindInField get FindInField(field,target,"true",start) where field is the name of the field or container to search target is the string to search for "true" is an option parameter to indicate case sensitivity for the search start is the (optional) starting byte offset EXAMPLE ex. get FindInField(card field 1,"EXAMPLE","true",0) REVISION HISTORY 1.1 4/31/88 - FindInField using HCLib was way too slow 1.2 5/5/88 - rewrite in more "C" style, one pass over the field 1.3 5/10/88 - add case sensitivity and starting position -- part contents for card part 7 ----- text ----- /* QuickFindInField1.3.c */ /* © Trustees of Dartmouth College */ /* written in LightSpeed C © Think Technologies, Inc */ /* by Roger Brown 5/10/88 Courseware Development Group */ /* add start byte input as last parameter */ /* This is a HyperCard XFCN that locates a target string in an input field (or other container) and returns the byte position in the field, the number of the line where it was find, and the byte position in that line. Case sensitivity is used if an optional third parameter is "true". Syntax is: get FindInField(container,target,"true") ex. get FindInField(card field 1,"***") returns: item 1: byte offset in field or 0 if not found item 2: line of card field 1 that contains '***' or 0 item 3: byte position in the line or 0 where container is any hypercard container (field, variable), presumed to be multi-lined. target is the string to look for true is an optional parameter turning on case sensitivity To compile: create a project with this and MacTraps. Build as code resource type XFCN named FindInField. */ #include "stddata_ctype.c" #include "strings.c" #include "ToolboxUtil.h" #include "HyperXCmd.h" #include "XCmdGlue.inc.c" /* change a string to all upper case */ int toupper(c) char c; { return( (c>='a')&&(c<='z') ? (c-('a'-'A')) : c ); } /* see if two characters match, maybe ignoring case */ matchChar(a,b,theCase) char a,b; int theCase; { if (theCase==0) return (a==b); return (toupper(a)==toupper(b)); } /* build the return result string from numeric parts */ BuildResult(fPos,fLine,lPos,result) int fPos,fLine,lPos; char *result; { char temp[64]; NumToString((long)fPos,temp); PtoCstr(temp); strcpy(result,temp); strcat(result,","); NumToString((long)fLine,temp); PtoCstr(temp); strcat(result,temp); strcat(result,","); NumToString((long)lPos,temp); PtoCstr(temp); strcat(result,temp); } /* find the target as specified */ FindIt(theField,theTarget,caseSens,result,start) char *theField; /* pointer to field to search */ char *theTarget; /* pointer to target string */ char *result; /* pointer to the return result string */ int caseSens,start; /* case sensitive = 1 for yes, start is where (byte) to start */ { int c; /* index of current character */ int tLen; /* target length */ int line; /* line currently being searched */ int lPos; /* character position in line */ register char *fc,*tc; /* pointers to field and target characters */ tLen = strlen(theTarget); /* assume this is short */ c = lPos = 0; line = 1; /* offset into theField */ fc = theField; /* pointer into theField */ while (*fc != 0) { /* scan to end */ tc = theTarget; /* pointer to theTarget */ if (*fc==13) { line++; /* passing a line boundary */ lPos = -1; /* reset position */ } if ((c+1) > start) { /* don't go until something matches */ while (matchChar(*tc,*fc,caseSens)) { /* check for match */ fc++; /* cycle through matching characters */ tc++; if (tc == (theTarget+tLen)){ /* all target characters matched */ BuildResult(c+1,line,lPos+1,result); return; /* matched */ } } } c++; /* move along */ lPos++; fc = theField + c; /* reset pointer after a search */ } BuildResult(0,0,0,result); return; /* target not found */ } /* XCMD entry */ pascal void FindInField(paramPtr) XCmdBlockPtr paramPtr; { int i; Str255 theResult,caseStr,startStr; Ptr theField,theTarget,casePtr,theStart; long line; Size len; CursHandle theCursor; Handle resultHandle; int theCase; long startAt; theCursor = GetCursor(watchCursor); SetCursor(*theCursor); for (i=0;iparamCount;i++) { MoveHHi(paramPtr->params[i]); HLock(paramPtr->params[i]); } theField = *(paramPtr->params[0]); theTarget = *(paramPtr->params[1]); if (paramPtr->paramCount>2) { casePtr = *(paramPtr->params[2]); strcpy(caseStr,casePtr); } else strcpy(caseStr,""); for (i=0;iparamCount>3) { theStart = *(paramPtr->params[3]); strcpy(startStr,theStart); CtoPstr(startStr); StringToNum(startStr,&startAt); } else startAt = 0; FindIt(theField,theTarget,theCase,theResult,(int)startAt); /* assemble the return string */ len = 1+strlen(theResult); resultHandle = NewHandle(len); HLock(resultHandle); BlockMove(theResult,*resultHandle,len); HUnlock(resultHandle); paramPtr->returnValue = resultHandle; for (i=0;iparamCount;i++) HUnlock (paramPtr->params[i]); return; } pascal void main(paramPtr) XCmdBlockPtr paramPtr; /* this is the entry point for the XFCN */ { FindInField(paramPtr); /* run the main event loop */ return; } -- part contents for card part 9 ----- text ----- 135,7,2